package com.xb.cloud.common.redis.template;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.Builder;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.util.SafeEncoder;


/**
 * 
 * @ClassName:  RedisClientTemplate   
 * @Description:TODO
 * @author: 鲜备科技
 * @date:   2017年12月21日 下午3:43:09   
 *     
 * @Copyright: 2017 www.xianbeitech.com Inc. All rights reserved. 
 *
 */
@Repository("redisClientTemplate")
public class RedisClientTemplate {

	private static final Logger logger = LoggerFactory.getLogger(RedisClientTemplate.class);
	
	@Autowired
	private ShardedJedisPool shardedJedisPool;
	
	
	public void returnResource(ShardedJedis shardedJedis, boolean broken) {
        if (broken) {
            shardedJedisPool.returnBrokenResource(shardedJedis);
        } else {
            shardedJedisPool.returnResource(shardedJedis);
        }
    }
	
	/**
	 * list尾部添加元素，如果队列不存在，会创建新的队列
	 * 
	 * @see link http://redis.cn/commands/rpush.html
	 * @return list长度
	 */
	public long rpush(String key, String string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		try {
			ret = shardedJedis.rpush(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
            shardedJedisPool.returnBrokenResource(shardedJedis);
		}finally {
			shardedJedisPool.returnResource(shardedJedis);
		}
		return ret;
	}
	
	/**
	 * list尾部添加元素，如果队列不存在，会创建新的队列
	 * 
	 * @see link http://redis.cn/commands/rpush.html
	 * @return list长度
	 */
	public long rpush(byte[] key, byte[] string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.rpush(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * list头部添加元素，如果队列不存在，会创建新的队列
	 * 
	 * @see link http://redis.cn/commands/lpush.html
	 * @return list长度
	 */
	public long lpush(String key, String string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lpush(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * list头部添加元素，如果队列不存在，会创建新的队列
	 * 
	 * @see link http://redis.cn/commands/lpush.html
	 * @return list长度
	 */
	public long lpush(byte[] key, byte[] string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lpush(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * list尾部添加元素，如果队列不存在，返回0
	 * 
	 * @see link http://redis.cn/commands/rpushx.html
	 * @return list长度
	 */
	public long rpushx(String key, String string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.rpushx(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * list尾部添加元素，如果队列不存在，返回0
	 * 
	 * @see link http://redis.cn/commands/rpushx.html
	 * @return list长度
	 */
	public long rpushx(byte[] key, byte[] string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.rpushx(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * list头部添加元素，如果队列不存在，返回0
	 * 
	 * @see link http://redis.cn/commands/lpushx.html
	 * @return list长度
	 */
	public long lpushx(String key, String string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lpushx(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * list头部添加元素，如果队列不存在，返回0
	 * 
	 * @see link http://redis.cn/commands/lpushx.html
	 * @return list长度
	 */
	public long lpushx(byte[] key, byte[] string) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lpushx(key, string);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 添加一个或者多个元素到集合(set)里
	 * @see link http://redis.cn/commands/sadd.html
	 * 返回新成功添加到集合里元素的数量，不包括已经存在于集合中的元素.
	 */
	public long sadd(String key, String... members) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.sadd(key, members);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 添加一个或者多个元素到集合(set)里
	 * @see link http://redis.cn/commands/sadd.html
	 * 返回新成功添加到集合里元素的数量，不包括已经存在于集合中的元素.
	 */
	public long sadd(byte[] key, byte[]... members) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.sadd(key, members);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 弹出头部元素
	 * 
	 * @see link http://redis.cn/commands/lpop.html
	 * @return string 头部元素
	 */
	public String lpop(String key) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "" ;
		boolean broken = false;
		try {
			ret = shardedJedis.lpop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 弹出头部元素
	 * 
	 * @see link http://redis.cn/commands/lpop.html
	 * @return string 头部元素
	 */
	public byte[] lpop(byte[] key) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null ;
		boolean broken = false;
		try {		
			ret = shardedJedis.lpop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 弹出尾部元素
	 * 
	 * @see link http://redis.cn/commands/rpop.html
	 * @return string 尾部元素
	 */
	public String rpop(String key) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "" ;
		boolean broken = false;
		try {
			ret = shardedJedis.rpop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 弹出尾部元素
	 * 
	 * @see link http://redis.cn/commands/rpop.html
	 * @return string 尾部元素
	 */
	public byte[] rpop(byte[] key) {
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null ;
		boolean broken = false;
		try {
			ret = shardedJedis.rpop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回列表里的元素的索引 index 存储在 key 里面。 下标是从0开始索引的，所以 0 是表示第一个元素， 1 表示第二个元素，并以此类推。
	 * 负数索引用于指定从列表尾部开始索引的元素。在这种方法下，-1 表示最后一个元素，-2 表示倒数第二个元素，并以此往前推。
	 * 当 key 位置的值不是一个列表的时候，会返回一个error。
	 * 
	 * @see link http://redis.cn/commands/lindex.html
	 * @return 请求的对应元素，或者当 index 超过范围的时候返回 nil。
	 */
	public String lindex(String key, long index) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "" ;
		boolean broken = false;
		try {
			ret = shardedJedis.lindex(key, index);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
	 * 当 key 不存在时，这个list会被看作是空list，任何操作都不会发生。
	 * 当 key 存在，但保存的不是一个list的时候，会返回error。
	 * 
	 * @see link http://redis.cn/commands/linsert.html
	 * @return 经过插入操作后的list长度，或者当 pivot 值找不到的时候返回 -1。
	 */
	public Long linsert(String key, LIST_POSITION where, String pivot, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0 ;
		boolean broken = false;
		try {
			ret = shardedJedis.linsert(key, where, pivot, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 把 value 插入存于 key 的列表中在基准值 pivot 的前面或后面。
	 * 当 key 不存在时，这个list会被看作是空list，任何操作都不会发生。
	 * 当 key 存在，但保存的不是一个list的时候，会返回error。
	 * 
	 * @see link http://redis.cn/commands/linsert.html
	 * @return 经过插入操作后的list长度，或者当 pivot 值找不到的时候返回 -1。
	 */
	public Long linsert(byte[] key, LIST_POSITION where, byte[] pivot, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0 ;
		boolean broken = false;
		try {
			ret = shardedJedis.linsert(key, where, pivot, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 设置队列里面一个元素的值
	 * 
	 * @see link http://redis.cn/commands/lset.html
	 * @return 成功 OK 当index超出范围时会返回一个error。
	 */
	public String lset(String key, long index, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.lset(key, index, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 获取LIST长度
	 * 
	 * @see link http://redis.cn/commands/llen.html
	 * @return list长度
	 */
	public long llen(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.llen(key);	
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 获取LIST长度
	 * 
	 * @see link http://redis.cn/commands/llen.html
	 * @return list长度
	 */
	public long llen(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.llen(key);	
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作：
	 * count > 0: 从头往尾移除值为 value 的元素。
	 * count < 0: 从尾往头移除值为 value 的元素。
	 * count = 0: 移除所有值为 value 的元素。
	 * 比如， LREM list -2 "hello" 会从存于 list 的列表里移除最后两个出现的 "hello"。
	 * 需要注意的是，如果list里没有存在key就会被当作空list处理，所以当 key 不存在的时候，这个命令会返回 0。
	 * 
	 * @see link http://redis.cn/commands/lrem.html
	 * @return list长度
	 */
	public long lrem(String key, long count, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lrem(key, count, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作：
	 * count > 0: 从头往尾移除值为 value 的元素。
	 * count < 0: 从尾往头移除值为 value 的元素。
	 * count = 0: 移除所有值为 value 的元素。
	 * 比如， LREM list -2 "hello" 会从存于 list 的列表里移除最后两个出现的 "hello"。
	 * 需要注意的是，如果list里没有存在key就会被当作空list处理，所以当 key 不存在的时候，这个命令会返回 0。
	 * 
	 * @see link http://redis.cn/commands/lrem.html
	 * @return list长度
	 */
	public long lrem(byte[] key, int count, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.lrem(key, count, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 修剪到指定范围内的清单
	 * 
	 * @see link http://redis.cn/commands/ltrim.html
	 * @return OK
	 */
	public String ltrim(String key, long start, long end) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.ltrim(key, start, end);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 获取key这个List，从第几个元素到第几个元素 LRANGE key start
	 * 
	 * @param key List别名
	 * @param start 开始下标
	 * @param end 结束下标
	 * @see link http://redis.cn/commands/lrange.html
	 * @return list
	 */
	public List<String> lrange(String key, long start, long end) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		List<String> list = null;
		boolean broken = false;
		try {
			list = shardedJedis.lrange(key, start, end);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return list;
	}

	/**
	 * 将哈希表key中的域field的值设为value。
	 * 
	 * @param key 哈希表别名
	 * @param field 键
	 * @param value 值
	 * @see link http://redis.cn/commands/hset.html
	 * 1如果field是一个新的字段
	 * 0如果field原来在map里面已经存在
	 */
	public Long hset(String key, String field, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = -1;
		boolean broken = false;
		try {
			ret = shardedJedis.hset(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 将哈希表key中的域field的值设为value。
	 * 
	 * @param key 哈希表别名
	 * @param field 键
	 * @param value 值
	 * @see link http://redis.cn/commands/hset.html
	 * 1如果field是一个新的字段
	 * 0如果field原来在map里面已经存在
	 */
	public Long hset(byte[] key, byte[] field, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = -1;
		boolean broken = false;
		try {
			ret = shardedJedis.hset(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * @param key
	 * @param value
	 * @see link http://redis.cn/commands/set.html
	 * @return 总是OK，因为SET不会失败。
	 */
	public String set(String key, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.set(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 获取key的值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/get.html
	 * @return value
	 */
	public String get(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.get(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 存入序列化的数据
	 * 
	 * @param key 序列化后的KEY
	 * @param value  序列化后的对象
	 * @return 总是OK，因为SET不会失败。
	 */
	public String set(byte[] key, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.set(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 取得序列化的数据
	 * 
	 * @param key 序列化后的KEY
	 * @return byte[] value
	 */
	public byte[] get(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.get(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	

	/**
	 * 获取key的有效时间（单位：秒）
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/ttl.html
	 * @return 获取key的有效时间（单位：秒）
	 */
	public long ttl(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.ttl(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 获取key的有效时间（单位：秒）
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/ttl.html
	 * @return 获取key的有效时间（单位：秒）
	 */
	public long ttl(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.ttl(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 删除key的值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/del.html
	 * @return 被删除的key的数量
	 */
	public long del(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.del(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 删除key的值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/del.html
	 * @return 被删除的key的数量
	 */
	public long del(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.del(new String(key));
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 设置 key 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。
	 * 如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key 关联
	 * @param key
	 * @param map
	 * @see link http://redis.cn/commands/hmset.html
	 * @return OK
	 */
	public String hmset(String key, Map<String, String> map) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.hmset(key, map);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 设置 key 指定的哈希集中指定字段的值。该命令将重写所有在哈希集中存在的字段。
	 * 如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key 关联
	 * @param key
	 * @param map
	 * @see link http://redis.cn/commands/hmset.html
	 * @return OK
	 */
	public String hmset(byte[] key, Map<byte[], byte[]> map) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.hmset(key, map);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 设置key对应字符串value，并且设置key在给定的seconds时间之后超时过期。这个命令等效于执行下面的命令：
	 * SET mykey value
	 * EXPIRE mykey seconds
	 * @param key
	 * @param seconds
	 *            生命周期 秒为单位
	 * @param value
	 * @see link http://redis.cn/commands/setex.html
	 * @return OK
	 */
	public String setex(String key, int seconds, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.setex(key, seconds, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 设置key对应字符串value，并且设置key在给定的seconds时间之后超时过期。这个命令等效于执行下面的命令：
	 * SET mykey value
	 * EXPIRE mykey seconds
	 * @param key
	 * @param seconds
	 *            生命周期 秒为单位
	 * @param value
	 * @see link http://redis.cn/commands/setex.html
	 * @return OK
	 */
	public String setex(byte[] key, int seconds, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.setex(key, seconds, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 将 key 的值设为 value ，当且仅当 key 不存在
	 * SET mykey value
	 * EXPIRE mykey seconds
	 * @param key
	 * @param seconds
	 *            生命周期 秒为单位
	 * @param value
	 * @see link http://redis.cn/commands/setnx.html
	 * @return OK
	 */
	public long setnx(String key, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.setnx(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 将 key 的值设为 value ，当且仅当 key 不存在
	 * SET mykey value
	 * EXPIRE mykey seconds
	 * @param key
	 * @param seconds
	 *            生命周期 秒为单位
	 * @param value
	 * @see link http://redis.cn/commands/setnx.html
	 * @return OK
	 */
	public long setnx(byte[] key, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.setnx(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 为给定key设置生命周期
	 * 
	 * @param key
	 * @param seconds 生命周期 秒为单位
	 * @see link http://redis.cn/commands/expire.html
	 * @return 1 如果设置了过期时间, 0 如果没有设置过期时间，或者不能设置过期时间
	 */
	public Long expire(String key, int seconds) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.expire(key, seconds);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 为给定key设置生命周期
	 * 
	 * @param key
	 * @param seconds 生命周期 秒为单位
	 * @see link http://redis.cn/commands/expire.html
	 * @return 1 如果设置了过期时间, 0 如果没有设置过期时间，或者不能设置过期时间
	 */
	public Long expire(byte[] key, int seconds) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.expire(key, seconds);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 为给定key设置过期时间戳
	 * 
	 * @param key
	 * @param unixTime UNIX 时间戳 Unix timestamp
	 * @see link http://redis.cn/commands/expireAt.html
	 * @return 1 如果设置了过期时间,0 如果没有设置过期时间，或者不能设置过期时间
	 */
	public Long expireAt(String key, long unixTime) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.expireAt(key, unixTime);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 为给定key设置过期时间戳
	 * 
	 * @param key
	 * @param unixTime UNIX 时间戳 Unix timestamp
	 * @see link http://redis.cn/commands/expireAt.html
	 * @return 1 如果设置了过期时间,0 如果没有设置过期时间，或者不能设置过期时间
	 */
	public Long expireAt(byte[] key, long unixTime) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.expireAt(key, unixTime);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 检查key是否存在
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/exists.html
	 * @return true/false
	 */
	public boolean exists(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.exists(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 检查key是否存在
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/exists.html
	 * @return true/false
	 */
	public boolean exists(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.exists(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回key值的类型 none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/type.html
	 * @return string, list, set, zset and hash, or none
	 */
	public String type(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.type(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回key值的类型 none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表)
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/type.html
	 * @return string, list, set, zset and hash, or none
	 */
	public String type(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.type(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 从哈希表key中获取field的value
	 * 
	 * @param key
	 * @param field
	 * @see link http://redis.cn/commands/hget.html
	 * @return 该字段所关联的值。当字段不存在或者 key 不存在时返回nil。
	 */
	public String hget(String key, String field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.hget(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 从哈希表key中获取field的value
	 * 
	 * @param key
	 * @param field
	 * @see link http://redis.cn/commands/hget.html
	 * @return 该字段所关联的值。当字段不存在或者 key 不存在时返回nil。
	 */
	public byte[] hget(byte[] key, byte[] field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.hget(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回哈希表key中，所有的域和值 默认无序
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<String, String> hgetAll(String key) {
		return hgetAll(key, false);
	}

	/**
	 * 返回哈希表key中，所有的域和值 默认无序
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<byte[], byte[]> hgetAll(byte[] key) {
		return hgetAll(key, false);
	}
	/**
	 * 返回哈希表key中，所有的域和值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<String, String> hgetAll(String key, boolean order) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Map<String, String> ret = null;
		boolean broken = false;
		try {
			if (order) {
				Jedis shard = shardedJedis.getShard(key);
				if (shard.getClient().isInMulti()) {
					throw new JedisDataException(
							"Cannot use Jedis when in Multi. Please use JedisTransaction instead.");
				}
				shard.getClient().hgetAll(key);
				ret = STRING_LINKEDHASHMAP.build(shard.getClient()
						.getBinaryMultiBulkReply());
			} else {
				ret = shardedJedis.hgetAll(key);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;

	}
	
	/**
	 * 返回哈希表key中，所有的域和值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<byte[], byte[]> hgetAll(byte[] key, boolean order) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Map<byte[], byte[]> ret = null;
		boolean broken = false;
		try {
			if (order) {
				Jedis shard = shardedJedis.getShard(key);
				if (shard.getClient().isInMulti()) {
					throw new JedisDataException(
							"Cannot use Jedis when in Multi. Please use JedisTransaction instead.");
				}
				shard.getClient().hgetAll(key);
				ret = BYTE_LINKEDHASHMAP.build(shard.getClient()
						.getBinaryMultiBulkReply());
			} else {
				ret = shardedJedis.hgetAll(key);
			}
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;

	}
	/**
	 * 返回哈希表key中，所有的域和值 默认有序
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<String, String> hgetAllToLinkedHashMap(String key) {
		return hgetAll(key, true);
	}
	
	public static final Builder<Map<byte[], byte[]>> BYTE_LINKEDHASHMAP = new Builder<Map<byte[], byte[]>>() {
		@SuppressWarnings("unchecked")
		public Map<byte[], byte[]> build(Object data) {
			final List<byte[]> flatHash = (List<byte[]>) data;
			final Map<byte[], byte[]> hash = new LinkedHashMap<byte[], byte[]>();
			final Iterator<byte[]> iterator = flatHash.iterator();
			while (iterator.hasNext()) {
				hash.put(iterator.next(),iterator.next());
			}

			return hash;
		}
		public String toString() {
			return "Map<byte[], byte[]>";
		}

	};
	
	public static final Builder<Map<String, String>> STRING_LINKEDHASHMAP = new Builder<Map<String, String>>() {
		@SuppressWarnings("unchecked")
		public Map<String, String> build(Object data) {
			final List<byte[]> flatHash = (List<byte[]>) data;
			final Map<String, String> hash = new LinkedHashMap<String, String>();
			final Iterator<byte[]> iterator = flatHash.iterator();
			while (iterator.hasNext()) {
				hash.put(SafeEncoder.encode(iterator.next()),
						SafeEncoder.encode(iterator.next()));
			}

			return hash;
		}
		public String toString() {
			return "Map<String, String>";
		}

	};
	/**
	 * 返回哈希表key中，所有的域和值 默认有序
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/hgetall.html
	 * @return 哈希集中字段和值的列表。当 key 指定的哈希集不存在时返回空列表。
	 */
	public Map<byte[], byte[]> hgetAllToLinkedHashMap(byte[] key) {
		return hgetAll(key, true);
	}

	/**
	 * 返回key集合所有的元素
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/smembers.html
	 * @return 集合中的所有元素
	 */
	public Set<String> smembers(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Set<String> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.smembers(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 返回key集合所有的元素
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/smembers.html
	 * @return 集合中的所有元素
	 */
	public Set<byte[]> smembers(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Set<byte[]> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.smembers(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 移除集合中的member元素
	 * 
	 * @param key  List别名
	 * @param field 键
	 * @see link http://redis.cn/commands/srem.html
	 * @return 从集合中移除元素的个数，不包括不存在的成员
	 */
	public Long srem(String key, String... field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.srem(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 移除集合中的member元素
	 * 
	 * @param key  List别名
	 * @param field 键
	 * @see link http://redis.cn/commands/srem.html
	 * @return 从集合中移除元素的个数，不包括不存在的成员
	 */
	public Long srem(byte[] key, byte[]... field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.srem(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回集合存储的key的基数 (集合元素的数量).
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/scard.html
	 * return 集合的基数(元素的数量),如果key不存在,则返回 0.
	 */
	public Long scard(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.scard(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回集合存储的key的基数 (集合元素的数量).
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/scard.html
	 * return 集合的基数(元素的数量),如果key不存在,则返回 0.
	 */
	public Long scard(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.scard(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 移除并且返回集合中的随机元素
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/spop.html
	 * return 被移除的元素, 当key不存在的时候返回 nil 
	 */
	public String spop(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.spop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 移除并且返回集合中的随机元素
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/spop.html
	 * return 被移除的元素, 当key不存在的时候返回 nil 
	 */
	public byte[] spop(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.spop(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回集合中的随机元素
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/srandmember.html
	 * return 集合中的随机元素,当key不存在的时候返回 nil 
	 */
	public String srandmember(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.srandmember(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回集合中的随机元素
	 * 
	 * @param key  List别名
	 * @see link http://redis.cn/commands/srandmember.html
	 * return 集合中的随机元素,当key不存在的时候返回 nil 
	 */
	public byte[] srandmember(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.srandmember(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 判断member元素是否是集合key的成员。是（true），否则（false）
	 * 
	 * @param key
	 * @param field
	 * @see link http://redis.cn/commands/sismember.html
	 * @return true/false
	 */
	public boolean sismember(String key, String field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.sismember(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 判断member元素是否是集合key的成员。是（true），否则（false）
	 * 
	 * @param key
	 * @param field
	 * @see link http://redis.cn/commands/sismember.html
	 * @return true/false
	 */
	public boolean sismember(byte[] key, byte[] field) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.sismember(key, field);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 如果 key 已经存在，并且值为字符串，那么这个命令会把 value 追加到原来值（value）的结尾。
	 * 如果 key 不存在，那么它将首先创建一个空字符串的key，再执行追加操作，这种情况 APPEND 将类似于 SET 操作。
	 * 
	 * @param key
	 * @param value
	 * @see link http://redis.cn/commands/append.html
	 * @return 返回append后字符串值（value）的长度。
	 */
	public Long append(String key, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.append(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 如果 key 已经存在，并且值为字符串，那么这个命令会把 value 追加到原来值（value）的结尾。
	 * 如果 key 不存在，那么它将首先创建一个空字符串的key，再执行追加操作，这种情况 APPEND 将类似于 SET 操作。
	 * 
	 * @param key
	 * @param value
	 * @see link http://redis.cn/commands/append.html
	 * @return 返回append后字符串值（value）的长度。
	 */
	public Long append(byte[] key, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.append(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * -- key
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/decr.html
	 * @return 减小之后的value
	 */
	public Long decr(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.decr(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * -- key
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/decr.html
	 * @return 减小之后的value
	 */
	public Long decr(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret  = shardedJedis.decr(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * key 减指定数值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/decrBy.html
	 * @return 减小之后的value
	 */
	public Long decrBy(String key, Integer integer) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.decrBy(key, integer);
			//incrCounter(cacheInRequestKey(shardedJedisPoolName, RedisConstants.REDIS_GET_HITS_KEY), 1);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * key 减指定数值
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/decrBy.html
	 * @return 减小之后的value
	 */
	public Long decrBy(byte[] key, Integer integer) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.decrBy(key, integer);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 这里的N是返回的string的长度。复杂度是由返回的字符串长度决定的，但是因为从一个已经存在的字符串创建一个子串是很容易的，所以对于较小的字符串，
	 * 可以认为是O(1)的复杂度。
	 * 
	 * @param key
	 * @see link http://redis.cn/commands/getrange.html
	 * @return 返回的string
	 */
	public String getrange(String key, int startOffset, int endOffset) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.getrange(key, startOffset, endOffset);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串，就返回错误。
	 * 
	 * @param key
	 * @param value
	 * @see link http://redis.cn/commands/getSet.html
	 * @return 原来key对应的value。如果key存在但是对应的value不是字符串，就返回错误
	 */
	public String getSet(String key, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		String ret = "";
		boolean broken = false;
		try {
			ret = shardedJedis.getSet(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 自动将key对应到value并且返回原来key对应的value。如果key存在但是对应的value不是字符串，就返回错误。
	 * 
	 * @param key
	 * @param value
	 * @see link http://redis.cn/commands/getSet.html
	 * @return 原来key对应的value。如果key存在但是对应的value不是字符串，就返回错误
	 */
	public byte[] getSet(byte[] key, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		byte[] ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.getSet(key, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	/**
	 * 从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。如果 key
	 * 指定的哈希集不存在，它将被认为是一个空的哈希集，该命令将返回0。
	 * 
	 * 返回值 整数：返回从哈希集中成功移除的域的数量，不包括指出但不存在的那些域
	 * 
	 * 
	 * 
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hdel.html
	 * @return 返回从哈希集中成功移除的域的数量，不包括指出但不存在的那些域
	 */
	public Long hdel(String key, String... fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.hdel(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。如果 key
	 * 指定的哈希集不存在，它将被认为是一个空的哈希集，该命令将返回0。
	 * 
	 * 返回值 整数：返回从哈希集中成功移除的域的数量，不包括指出但不存在的那些域
	 * 
	 * 
	 * 
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hdel.html
	 * @return 返回从哈希集中成功移除的域的数量，不包括指出但不存在的那些域
	 */
	public Long hdel(byte[] key, byte[]... fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.hdel(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回字段是否是 key 指定的哈希集中存在的字段。
	 * 
	 * 返回值 整数, 含义如下：
	 * 
	 * 1 哈希集中含有该字段。 0 哈希集中不含有该存在字段，或者key不存在。
	 * 
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hexists.html
	 * @return 1 哈希集中含有该字段。 0 哈希集中不含有该存在字段，或者key不存在
	 */
	public Boolean hexists(String key, String fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.hexists(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回字段是否是 key 指定的哈希集中存在的字段。
	 * 
	 * 返回值 整数, 含义如下：
	 * 
	 * 1 哈希集中含有该字段。 0 哈希集中不含有该存在字段，或者key不存在。
	 * 
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hexists.html
	 * @return 1 哈希集中含有该字段。 0 哈希集中不含有该存在字段，或者key不存在
	 */
	public Boolean hexists(byte[] key, byte[] fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		boolean ret = false;
		boolean broken = false;
		try {
			ret = shardedJedis.hexists(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 增加 key 指定的哈希集中指定字段的数值。如果 key 不存在，会创建一个新的哈希集并与 key
	 * 关联。如果字段不存在，则字段的值在该操作执行前被设置为 0
	 * 
	 * HINCRBY 支持的值的范围限定在 64位 有符号整数
	 * 
	 * 返回值 整数：增值操作执行后的该字段的值。
	 * 
	 * @param key
	 * @param fields
	 * @param value
	 * @see link http://redis.cn/commands/hincrBy.html
	 * @return 增值操作执行后的该字段的值
	 */
	public Long hincrBy(String key, String field, int value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.hincrBy(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 增加 key 指定的哈希集中指定字段的数值。如果 key 不存在，会创建一个新的哈希集并与 key
	 * 关联。如果字段不存在，则字段的值在该操作执行前被设置为 0
	 * 
	 * HINCRBY 支持的值的范围限定在 64位 有符号整数
	 * 
	 * 返回值 整数：增值操作执行后的该字段的值。
	 * 
	 * @param key
	 * @param fields
	 * @param value
	 * @see link http://redis.cn/commands/hincrBy.html
	 * @return 增值操作执行后的该字段的值
	 */
	public Long hincrBy(byte[] key, byte[] field, int value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret  = shardedJedis.hincrBy(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回 key 指定的哈希集中所有字段的名字。
	 * 
	 * 返回值 多个返回值：哈希集中的字段列表，当 key 指定的哈希集不存在时返回空列表。
	 * @param key
	 * 
	 * @see link http://redis.cn/commands/hkeys.html
	 * @return 哈希集中的字段列表
	 */
	public Set<String> hkeys(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Set<String> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.hkeys(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回 key 指定的哈希集中所有字段的名字。
	 * 
	 * 返回值 多个返回值：哈希集中的字段列表，当 key 指定的哈希集不存在时返回空列表。
	 * @param key
	 * 
	 * @see link http://redis.cn/commands/hkeys.html
	 * @return 哈希集中的字段列表
	 */
	public Set<byte[]> hkeys(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		Set<byte[]> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.hkeys(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}

	/**
	 * 返回 key 指定的哈希集包含的字段的数量。
	 * 
	 * 返回值 整数：哈希集中字段的数量，当 key 指定的哈希集不存在时返回 0 
	 * @param key
	 * @see link http://redis.cn/commands/hlen.html
	 * @return 哈希集中字段的数量
	 */
	public Long hlen(String key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.hlen(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回 key 指定的哈希集包含的字段的数量。
	 * 
	 * 返回值 整数：哈希集中字段的数量，当 key 指定的哈希集不存在时返回 0 
	 * @param key
	 * @see link http://redis.cn/commands/hlen.html
	 * @return 哈希集中字段的数量
	 */
	public Long hlen(byte[] key) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = 0;
		boolean broken = false;
		try {
			ret = shardedJedis.hlen(key);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回 key 指定的哈希集中指定字段的值。
	 * 
	 * 对于哈希集中不存在的每个字段，返回 nil 值。因为不存在的keys被认为是一个空的哈希集，对一个不存在的 key 执行 HMGET
	 * 将返回一个只含有 nil 值的列表
	 * 
	 * 返回值 多个返回值：含有给定字段及其值的列表，并保持与请求相同的顺序。
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hmget.html
	 * @return 含有给定字段及其值的列表，并保持与请求相同的顺序。
	 */
	public List<String> hmget(String key, String... fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		List<String> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.hmget(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 返回 key 指定的哈希集中指定字段的值。
	 * 
	 * 对于哈希集中不存在的每个字段，返回 nil 值。因为不存在的keys被认为是一个空的哈希集，对一个不存在的 key 执行 HMGET
	 * 将返回一个只含有 nil 值的列表
	 * 
	 * 返回值 多个返回值：含有给定字段及其值的列表，并保持与请求相同的顺序。
	 * @param key
	 * @param fields
	 * @see link http://redis.cn/commands/hmget.html
	 * @return 含有给定字段及其值的列表，并保持与请求相同的顺序。
	 */
	public List<byte[]> hmget(byte[] key, byte[]... fields) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		List<byte[]> ret = null;
		boolean broken = false;
		try {
			ret = shardedJedis.hmget(key, fields);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 只在 key 指定的哈希集中不存在指定的字段时，设置字段的值。如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key
	 * 关联。如果字段已存在，该操作无效果。
	 * 
	 * 返回值 整数：含义如下
	 * 
	 * 1：如果字段是个新的字段，并成功赋值 0：如果哈希集中已存在该字段，没有操作被执行
	 * @param key
	 * 
	 * @see link http://redis.cn/commands/hsetnx.html
	 * @return 1：如果字段是个新的字段，并成功赋值 0：如果哈希集中已存在该字段，没有操作被执行
	 */
	public Long hsetnx(String key, String field, String value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = -1; 
		boolean broken = false;
		try {
			ret = shardedJedis.hsetnx(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	/**
	 * 只在 key 指定的哈希集中不存在指定的字段时，设置字段的值。如果 key 指定的哈希集不存在，会创建一个新的哈希集并与 key
	 * 关联。如果字段已存在，该操作无效果。
	 * 
	 * 返回值 整数：含义如下
	 * 
	 * 1：如果字段是个新的字段，并成功赋值 0：如果哈希集中已存在该字段，没有操作被执行
	 * @param key
	 * 
	 * @see link http://redis.cn/commands/hsetnx.html
	 * @return 1：如果字段是个新的字段，并成功赋值 0：如果哈希集中已存在该字段，没有操作被执行
	 */
	public Long hsetnx(byte[] key, byte[] field, byte[] value) {
		
		ShardedJedis shardedJedis = shardedJedisPool.getResource();
		long ret = -1; 
		boolean broken = false;
		try {
			ret = shardedJedis.hsetnx(key, field, value);
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			broken = true;
		}finally {
			returnResource(shardedJedis, broken);
		}
		return ret;
	}
	
	
}
